package test.serverframe.armc.server.manager.service.exec;

import com.microcore.util.SpringContextUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import test.serverframe.armc.server.manager.dao.mapper.InvokeTaskRecordMapper;
import test.serverframe.armc.server.manager.dao.mapper.TaskEnterInterfaceMapper;
import test.serverframe.armc.server.manager.dao.mapper.TaskEnterInvokeMapper;
import test.serverframe.armc.server.manager.dao.mapper.TaskMapper;
import test.serverframe.armc.server.manager.domain.InvokeTaskRecord;
import test.serverframe.armc.server.manager.domain.Task;
import test.serverframe.armc.server.manager.domain.TaskEnterInterface;
import test.serverframe.armc.server.manager.domain.TaskEnterInvoke;
import test.serverframe.armc.server.manager.service.exec.dag.DagNode;
import test.serverframe.armc.server.manager.service.exec.dag.NodeInfo;
import test.serverframe.armc.server.manager.service.exec.params.TaskExecutorParams;
import test.serverframe.armc.server.manager.service.exec.params.TaskInvokeExecutorParams;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * 任务调度执行者
 *
 * @author LiuChunfu
 * @date 2019.01.19
 */
public class TaskInvokeExecutor extends BaseExecutor {

	private Logger logger = LoggerFactory.getLogger(TaskInvokeExecutor.class);

	/**
	 * 任务调度执行参数
	 */
	private TaskInvokeExecutorParams params;

	/**
	 * 任务关联调度服务
	 */
	private TaskEnterInvokeMapper taskEnterInvokeMapper = SpringContextUtils.getBean("taskEnterInvokeMapper",
			TaskEnterInvokeMapper.class);

	/**
	 * 任务服务
	 */
	private TaskMapper taskMapper = SpringContextUtils.getBean("taskMapper", TaskMapper.class);

	/**
	 * 任务记录服务
	 */
	private InvokeTaskRecordMapper taskRecordMapper = SpringContextUtils.getBean("invokeTaskRecordMapper",
			InvokeTaskRecordMapper.class);

	/**
	 * 任务关联接口服务
	 */
	private TaskEnterInterfaceMapper taskEnterInterfaceMapper = SpringContextUtils.getBean("taskEnterInterfaceMapper",
			TaskEnterInterfaceMapper.class);

	public TaskInvokeExecutor(TaskInvokeExecutorParams params) {
		this.params = params;
	}

	@Override
	public List<NodeInfo> getNodeInfo() {
		// 通过任务调度id查询子任务Id集合
		List<TaskEnterInvoke> list = taskEnterInvokeMapper.selectByTaskInvokeId(params.getTaskInvokeId());
		List<NodeInfo> nodeList = new ArrayList<>();
		list.forEach(tei -> {
			NodeInfo nodeInfo = new NodeInfo(tei.getTaskId(), convert2List(tei.getTaskParentIds()),
					convert2List(tei.getTaskChildIds()));
			nodeList.add(nodeInfo);
		});
		return nodeList;
	}

	@Override
	public Runnable getNodeExecutor(DagNode node) {

		// 根据调度id查询任务图
		InvokeTaskRecord taskRecord = new InvokeTaskRecord();
		Task task = null;
		try {
			// 任务延时执行
			TaskEnterInvoke tei = new TaskEnterInvoke();
			tei.setTaskId(node.getId());
			tei.setTaskInvokeId(params.getTaskInvokeId());
			List<Integer> taskDelays = taskEnterInvokeMapper.findDelay(tei);
			int taskDelay = 0;
			if (null != taskDelays && taskDelays.size() > 0) {
				taskDelay = taskDelays.get(0);
			}
			logger.info("task delay: " + taskDelay + "s, taskId: " + node.getId());
			Thread.sleep(taskDelay * 1000);

			task = taskMapper.selectByPrimaryKey(node.getId());
			List<TaskEnterInterface> list = taskEnterInterfaceMapper.selectByTaskIds(node.getId());
			if (task != null) {

				// 初始化任务记录的执行状态
				String taskRecordId = UUID.randomUUID().toString();
				taskRecord.setInvokeTaskRecordId(taskRecordId);
				taskRecord.setStatus(Constants.EXECUTING);
				taskRecord.setVersion(task.getVersion());
				taskRecord.setTaskGroupId(task.getTaskGroupId());
				taskRecord.setInvokeRecordId(params.getInvokeRecordId());
				taskRecord.setStartTime(new Date());
				taskRecord.setInterfaceSuccessTotal(String.valueOf(0));
				taskRecord.setInterfaceTotal(String.valueOf(list.size()));
				taskRecord.setNodeArr(task.getNodeArr());

				// 传递任务执行时需要的参数
				TaskExecutorParams taskExecutorParams = new TaskExecutorParams();
				taskExecutorParams.setTaskId(node.getId());
				taskExecutorParams.setTaskTotal(params.getTaskTotal());
				taskExecutorParams.setSuccessTaskTotal(params.getSuccessTaskTotal());
				taskExecutorParams.setInvokeRecordId(params.getInvokeRecordId());
				taskExecutorParams.setExpectedTaskTotal(params.getExpectedTaskTotal());
				taskExecutorParams.setDagNode(node);
				taskExecutorParams.setFailedStrategy(params.getFailedStrategy());
				taskExecutorParams.setTaskRecordId(taskRecordId);
				taskExecutorParams.setTaskInvokeId(params.getTaskInvokeId());
				taskExecutorParams.setIsReStart(params.getIsReStart());
				logger.info("taskExecutorParams: " + taskExecutorParams);
				return new TaskExecutor(taskExecutorParams);
			} else {
				logger.warn("调度不存在，停止执行， 调度id：" + params.getTaskInvokeId());
			}
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(e.getMessage());
		} finally {
			if (task != null) {
				taskRecordMapper.insert(taskRecord);
			}
			
		}
		return null;
	}
}
